package main

import (
	"fmt"
	"strings"

	"github.com/pgparser/pkg/parser"
)

// 错误处理测试用例
var errorTestCases = []struct {
	name        string
	description string
	sql         string
	expectedErr bool
}{
	{
		name:        "语法错误 - 缺少FROM",
		description: "SELECT语句缺少FROM子句",
		sql:         "SELECT name, age;",
		expectedErr: true,
	},
	{
		name:        "语法错误 - 无效的WHERE条件",
		description: "WHERE子句语法错误",
		sql:         "SELECT * FROM users WHERE AND age > 18;",
		expectedErr: true,
	},
	{
		name:        "语法错误 - 不匹配的括号",
		description: "括号不匹配",
		sql:         "SELECT * FROM users WHERE (age > 18;",
		expectedErr: true,
	},
	{
		name:        "语法错误 - 无效的JOIN语法",
		description: "JOIN语法错误",
		sql:         "SELECT * FROM users JOIN ON orders.user_id = users.id;",
		expectedErr: true,
	},
	{
		name:        "词法错误 - 无效的字符串",
		description: "未闭合的字符串字面量",
		sql:         "SELECT * FROM users WHERE name = 'John;",
		expectedErr: true,
	},
	{
		name:        "语法错误 - 无效的ORDER BY",
		description: "ORDER BY语法错误",
		sql:         "SELECT * FROM users ORDER BY;",
		expectedErr: true,
	},
	{
		name:        "正确的查询",
		description: "语法正确的查询",
		sql:         "SELECT name, age FROM users WHERE age > 18;",
		expectedErr: false,
	},
	{
		name:        "语法错误 - 无效的聚合函数",
		description: "聚合函数语法错误",
		sql:         "SELECT COUNT( FROM users;",
		expectedErr: true,
	},
}

func main() {
	fmt.Println("=== PostgreSQL解析器错误处理示例 ===")
	fmt.Println("本示例展示如何处理各种解析错误并提供有用的错误信息")
	fmt.Println()

	// 测试各种错误情况
	for i, testCase := range errorTestCases {
		fmt.Printf("测试用例 %d: %s\n", i+1, testCase.name)
		fmt.Printf("描述: %s\n", testCase.description)
		fmt.Printf("SQL: %s\n", testCase.sql)
		fmt.Println("---")

		// 尝试解析SQL
		ast, err := parser.Parse(testCase.sql)
		if err != nil {
			if testCase.expectedErr {
				fmt.Printf("✅ 预期的错误: %v\n", err)
				// 分析错误类型和位置
				analyzeError(err, testCase.sql)
			} else {
				fmt.Printf("❌ 意外的错误: %v\n", err)
			}
		} else {
			if testCase.expectedErr {
				fmt.Printf("❌ 应该出错但解析成功\n")
			} else {
				fmt.Printf("✅ 解析成功\n")
				// 显示AST结构的简要信息
				showASTSummary(ast)
			}
		}

		fmt.Println("================================================================================")
		fmt.Println()
	}

	// 演示错误恢复机制
	fmt.Println("=== 错误恢复机制演示 ===")
	demonstateErrorRecovery()

	// 演示批量解析错误处理
	fmt.Println("\n=== 批量解析错误处理 ===")
	demonstrateBatchErrorHandling()
}

// analyzeError 分析错误类型和提供详细信息
func analyzeError(err error, sql string) {
	errorStr := err.Error()
	fmt.Printf("错误分析:\n")

	// 检查是否是语法错误
	if strings.Contains(errorStr, "syntax error") {
		fmt.Printf("  - 错误类型: 语法错误\n")
		// 尝试提取错误位置
		if strings.Contains(errorStr, "position") {
			fmt.Printf("  - 错误位置信息已包含在错误消息中\n")
		}
	} else if strings.Contains(errorStr, "unexpected") {
		fmt.Printf("  - 错误类型: 意外的标记\n")
	} else {
		fmt.Printf("  - 错误类型: 其他解析错误\n")
	}

	// 提供修复建议
	provideSuggestions(errorStr, sql)
}

// provideSuggestions 根据错误类型提供修复建议
func provideSuggestions(errorStr, sql string) {
	fmt.Printf("修复建议:\n")

	if strings.Contains(sql, "SELECT") && !strings.Contains(sql, "FROM") {
		fmt.Printf("  - SELECT语句通常需要FROM子句指定数据源\n")
	}

	if strings.Contains(sql, "WHERE AND") || strings.Contains(sql, "WHERE OR") {
		fmt.Printf("  - WHERE子句不能以AND或OR开头\n")
	}

	if strings.Count(sql, "(") != strings.Count(sql, ")") {
		fmt.Printf("  - 检查括号是否匹配\n")
	}

	if strings.Contains(sql, "'") && strings.Count(sql, "'")%2 != 0 {
		fmt.Printf("  - 检查字符串字面量是否正确闭合\n")
	}

	if strings.Contains(sql, "JOIN ON") && strings.Contains(sql, "JOIN ON") {
		fmt.Printf("  - JOIN语句需要指定表名\n")
	}

	if strings.Contains(sql, "ORDER BY;") {
		fmt.Printf("  - ORDER BY子句需要指定排序列\n")
	}
}

// showASTSummary 显示AST的简要信息
func showASTSummary(node parser.Node) {
	if node == nil {
		fmt.Printf("AST: <nil>\n")
		return
	}

	switch stmt := node.(type) {
	case *parser.SelectStmt:
		fmt.Printf("AST: SELECT语句\n")
		fmt.Printf("  - 目标列数: %d\n", len(stmt.Targets))
		if len(stmt.From) > 0 {
			fmt.Printf("  - 数据源数: %d\n", len(stmt.From))
		}
		if stmt.Where != nil {
			fmt.Printf("  - 包含WHERE条件\n")
		}
		if len(stmt.OrderBy) > 0 {
			fmt.Printf("  - 包含ORDER BY子句\n")
		}
	default:
		fmt.Printf("AST: %T\n", stmt)
	}
}

// demonstateErrorRecovery 演示错误恢复机制
func demonstateErrorRecovery() {
	// 模拟一个包含多个语句的SQL脚本，其中一些有错误
	sqlScript := []string{
		"SELECT name FROM users;",                    // 正确
		"SELECT * FROM WHERE age > 18;",              // 错误：缺少表名
		"SELECT age, COUNT(*) FROM users GROUP BY age;", // 正确
		"INSERT INTO users VALUES ('John';",          // 错误：括号不匹配
		"SELECT * FROM users ORDER BY name;",         // 正确
	}

	fmt.Println("处理包含错误的SQL脚本:")
	successCount := 0
	errorCount := 0

	for i, sql := range sqlScript {
		fmt.Printf("\n语句 %d: %s\n", i+1, sql)
		_, err := parser.Parse(sql)
		if err != nil {
			fmt.Printf("❌ 解析失败: %v\n", err)
			errorCount++
			// 在实际应用中，这里可以记录错误并继续处理下一个语句
			fmt.Printf("⚠️  跳过此语句，继续处理下一个...\n")
		} else {
			fmt.Printf("✅ 解析成功\n")
			successCount++
		}
	}

	fmt.Printf("\n处理结果: %d个成功, %d个失败\n", successCount, errorCount)
}

// demonstrateBatchErrorHandling 演示批量解析错误处理
func demonstrateBatchErrorHandling() {
	queries := []string{
		"SELECT * FROM users;",
		"SELECT name FROM;",  // 错误
		"SELECT age FROM users WHERE age > 18;",
		"SELECT COUNT(*) FROM users GROUP BY department;",
		"SELECT * FROM users WHERE (age > 18;", // 错误
	}

	results := make([]ParseResult, len(queries))

	// 批量解析
	for i, query := range queries {
		ast, err := parser.Parse(query)
		results[i] = ParseResult{
			Query:   query,
			AST:     ast,
			Error:   err,
			Success: err == nil,
		}
	}

	// 生成错误报告
	generateErrorReport(results)
}

// ParseResult 解析结果结构
type ParseResult struct {
	Query   string
	AST     parser.Node
	Error   error
	Success bool
}

// generateErrorReport 生成错误报告
func generateErrorReport(results []ParseResult) {
	successCount := 0
	errorCount := 0

	fmt.Println("批量解析结果报告:")
	fmt.Println("==================")

	for i, result := range results {
		fmt.Printf("\n查询 %d: %s\n", i+1, result.Query)
		if result.Success {
			fmt.Printf("状态: ✅ 成功\n")
			successCount++
		} else {
			fmt.Printf("状态: ❌ 失败\n")
			fmt.Printf("错误: %v\n", result.Error)
			errorCount++
		}
	}

	fmt.Printf("\n总结:\n")
	fmt.Printf("- 成功解析: %d 个查询\n", successCount)
	fmt.Printf("- 解析失败: %d 个查询\n", errorCount)
	fmt.Printf("- 成功率: %.1f%%\n", float64(successCount)/float64(len(results))*100)

	if errorCount > 0 {
		fmt.Printf("\n错误类型统计:\n")
		analyzeErrorPatterns(results)
	}
}

// analyzeErrorPatterns 分析错误模式
func analyzeErrorPatterns(results []ParseResult) {
	errorTypes := make(map[string]int)

	for _, result := range results {
		if !result.Success {
			errorStr := result.Error.Error()
			if strings.Contains(errorStr, "syntax error") {
				errorTypes["语法错误"]++
			} else if strings.Contains(errorStr, "unexpected") {
				errorTypes["意外标记"]++
			} else {
				errorTypes["其他错误"]++
			}
		}
	}

	for errorType, count := range errorTypes {
		fmt.Printf("- %s: %d 次\n", errorType, count)
	}
}